자바 언어 보안의 내재적 견고성과 생태계의 책임

자바 언어 보안의 내재적 견고성과 생태계의 책임

1. 서론: “자바는 안전한가?” 질문에 대한 재해석

“자바 언어 자체가 보안 이슈가 많은가?“라는 질문은 기술 커뮤니티에서 오랜 기간 반복되어 온 담론이다. 이 질문에 대한 답은 단순한 ‘예’ 또는 ’아니오’로 귀결될 수 없는 복합적인 성격을 띤다. 이는 자바 플랫폼의 **설계적 보안(Security by Design)**과, 그 위에서 동작하는 애플리케이션의 **구현상 보안(Security in Implementation)**이라는 두 가지 차원을 명확히 구분해야 하는 문제이기 때문이다. 언어와 플랫폼이 제공하는 내재적 견고성과 개발자가 작성한 코드 및 외부 라이브러리 생태계에서 발생하는 취약점은 별개의 논제로 분석되어야 한다.

본 보고서는 이 두 가지 핵심 측면을 심층적으로 분석하여 자바의 보안 패러다임에 대한 종합적인 결론을 도출하는 것을 목표로 한다. 보고서는 총 3부로 구성된다.

  • 1부에서는 자바가 설계 단계부터 어떻게 보안을 핵심 철학으로 삼았는지, 그리고 C/C++와 같은 언어에서 고질적으로 발생하는 특정 유형의 치명적인 취약점을 원천적으로 방지하는 구조적 장점들을 기술적으로 분석한다.

  • 2부에서는 자바의 보안에 대한 부정적 인식이 형성된 역사적 배경을 추적하고, 그것이 현대 자바 플랫폼에 대한 유효한 비판인지 검증한다. 더 나아가, 플랫폼의 문제가 아닌 개발 관행의 문제로 발생하는 현대 애플리케이션의 핵심 보안 도전 과제를 심도 있게 다룬다.

  • 3부에서는 끊임없이 진화하는 위협 환경에 대응하여 자바의 보안 패러다임이 어떻게 발전하고 있는지를 최신 장기 지원(Long-Term Support, LTS) 릴리스에 도입된 구체적인 기술적 진보를 통해 조명한다.

이러한 다각적인 분석을 통해, 본 보고서는 자바의 보안이 플랫폼, 개발자, 그리고 생태계가 함께 책임을 지는 ’공유 책임 모델(Shared Responsibility Model)’의 성격을 띠고 있음을 명확히 하고, 안전한 자바 애플리케이션 구축을 위한 전략적 제언을 제시할 것이다.

2. 부: 설계에 각인된 보안: 자바 플랫폼의 내재적 방어 기제

자바 언어와 가상 머신(JVM)은 탄생 초기부터 보안을 핵심 설계 철학으로 삼았다. 이는 네트워크를 통해 코드가 이동하고 다양한 환경에서 실행되는 것을 전제로 했기 때문이다. 이 장에서는 자바 플랫폼이 어떻게 저수준(low-level)의 보안 위협을 원천적으로 차단하는지, 그 내재적 방어 기제를 심층적으로 분석한다.

2.1 JVM과 샌드박스: 격리된 실행 환경의 원리

자바 보안의 가장 근본적인 개념은 신뢰할 수 없는 코드를 격리된 환경에서 실행하는 ‘샌드박스(Sandbox)’ 모델이다.1 샌드박스는 외부로부터 받은 프로그램을 보호된 영역 안에 가두어 실행함으로써, 해당 프로그램이 시스템 자원에 무단으로 접근하거나 악의적인 행위를 수행하는 것을 방지하는 핵심적인 보안 기술이다.1

이 모델은 단순한 기능이 아니라, 자바의 핵심 철학인 “한 번 작성하면 어디서든 실행된다(Write Once, Run Anywhere)“를 안전하게 구현하기 위한 필수적인 아키텍처다. 초기에는 네트워크를 통해 전송된 자바 애플릿(Applet)이 사용자의 로컬 파일 시스템을 읽거나 변경하는 등의 위험한 작업을 수행하지 못하도록 격리하는 것이 주된 목적이었다.1 하지만 이 격리 실행의 개념은 오늘날의 컨테이너 기술이나 다양한 가상화 기반 보안 솔루션의 사상적 토대가 되었다는 점에서 시대를 앞서간 설계였다고 평가할 수 있다.4

기술적으로 샌드박스는 외부 프로그램을 가상화된 내부 공간에서 시험적으로 동작시켜, 그 영향이 가상 환경 밖의 실제 시스템으로 전파되지 않도록 차단하는 원리로 작동한다.4 이 강력한 방어벽은 다음과 같은 세 가지 핵심 컴포넌트의 유기적인 상호작용을 통해 구축된다.3

  1. 클래스 로더 (Class Loader): 자바 클래스 파일을 JVM 메모리로 가져오는 역할을 하며, 각 클래스가 속한 네임스페이스를 정의하여 신뢰할 수 없는 코드가 다른 프로그램의 실행을 방해하지 못하도록 격리한다.5

  2. 바이트코드 검사기 (Bytecode Verifier): 클래스 로더가 로드한 코드가 JVM에서 실행되기 전에, 해당 코드가 유효하고 안전한지 검증하는 역할을 한다.

  3. 보안 관리자 (Security Manager): 런타임에 특정 작업(예: 파일 읽기, 네트워크 연결)이 허용되는지 여부를 보안 정책에 따라 검사하고 강제한다.6

이처럼 샌드박스는 다층적인 방어 구조를 통해 신뢰할 수 없는 코드가 시스템에 미칠 수 있는 잠재적 위협을 최소화하는, 자바 보안 아키텍처의 근간을 이룬다.

2.2 바이트코드 검증과 클래스 로딩: 신뢰의 첫 관문

자바의 보안 모델은 컴파일된 코드를 무조건 신뢰하지 않는다는 전제에서 출발한다. 자바 컴파일러(javac)는 개발자가 작성한 소스 코드(.java 파일)를 플랫폼에 독립적인 중간 코드인 ‘바이트코드’(.class 파일)로 변환한다.8 이 바이트코드는 JVM이 설치된 모든 운영체제에서 동일하게 실행될 수 있는 기반을 제공하지만, 동시에 악의적으로 조작될 가능성도 내포한다.

JVM은 이러한 위협에 대응하기 위해 클래스 로더가 바이트코드를 메모리에 로드하는 과정에서 ’검증(Verification)’이라는 매우 중요한 단계를 거친다.9 바이트코드 검사기(Bytecode Verifier)에 의해 수행되는 이 과정은 자바 보안의 핵심적인 첫 번째 방어선 역할을 한다. 검사기는 로드된 .class 파일이 다음과 같은 엄격한 규칙을 준수하는지 철저히 확인한다.

  • 자바 언어 명세 준수: 클래스 파일 형식이 유효한지, 자바 언어의 규칙을 위반하지 않는지 확인한다.10

  • 메모리 무결성 검사: 포인터 조작, 메모리 접근 위반, 스택 오버플로우 또는 언더플로우와 같이 JVM의 메모리 구조를 손상시킬 수 있는 악의적인 코드가 포함되어 있는지 검사한다.12

  • 타입 안전성 검사: 불법적인 데이터 타입 변환(illegal data typecasts)이 없는지 확인한다.12

  • 네임스페이스 및 접근 제어 규칙 준수: 클래스가 허용되지 않은 다른 클래스의 멤버에 접근하려 하거나, 네임스페이스 규칙을 위반하는지 검사한다.14

만약 검증 과정에서 손상되었거나 악의적으로 조작된 바이트코드가 발견되면, JVM은 VerifyError와 같은 예외를 발생시켜 해당 코드의 실행을 원천적으로 차단한다.10 이는 컴파일된 결과물을 무조건 신뢰하지 않고, 실행 직전에 다시 한번 무결성을 검증하는 ‘제로 트러스트(Zero Trust)’ 원칙의 초기 구현으로 볼 수 있다.

더 나아가, 보안 클래스 로딩 메커니즘은 각 클래스 파일에 고유한 네임스페이스를 부여하고 규칙을 강제함으로써, 공격자가 신뢰할 수 있는 시스템 클래스를 위조하여 악성 코드를 실행시키는 것을 방지하는 중요한 역할을 수행한다.14 이처럼 바이트코드 검증과 보안 클래스 로딩은 악성 코드가 JVM 내부로 침투하는 것을 막는 강력한 첫 번째 방어벽이다.

2.3 언어 수준의 안전망: 메모리 손상 취약점의 원천적 방어

자바 언어의 설계는 C나 C++와 같은 시스템 프로그래밍 언어에서 가장 심각하고 고질적인 보안 문제로 지적되는 메모리 손상 취약점(Memory Corruption Vulnerabilities)을 근본적으로 제거하는 데 초점을 맞추고 있다. 이는 단순히 부가적인 보안 기능을 추가한 것이 아니라, 언어의 핵심적인 특성을 통해 특정 종류의 공격을 원천적으로 불가능하게 만든다는 점에서 자바 보안의 가장 강력한 측면으로 평가된다.

2.3.1 가비지 컬렉션(Garbage Collection)을 통한 메모리 안전성 확보

C/C++에서는 개발자가 malloc/free 또는 new/delete를 사용하여 수동으로 메모리를 할당하고 해제해야 한다.16 이러한 수동 관리는 높은 성능과 제어력을 제공하지만, 인간의 실수로 인해 치명적인 보안 취약점을 유발할 수 있다. 예를 들어, 이미 해제된 메모리에 접근하는 ‘댕글링 포인터(dangling pointer)’ 문제나, 할당된 메모리 공간을 해제하지 않아 발생하는 ’메모리 누수(memory leak)’는 애플리케이션의 비정상적인 종료를 유발하거나 공격자에게 시스템 제어권을 넘겨주는 통로가 될 수 있다.18

반면, 자바는 자동 메모리 관리, 즉 가비지 컬렉션(Garbage Collection, GC)을 채택했다.5 JVM의 가비지 컬렉터는 더 이상 프로그램에서 참조되지 않는 객체(unreachable objects)를 자동으로 식별하고, 해당 객체가 차지하던 메모리를 회수한다.20 이로 인해 개발자는 메모리 해제에 대해 신경 쓸 필요가 없으며, 다음과 같은 메모리 관련 취약점이 원천적으로 방지된다.21

  • Use-After-Free: 이미 해제된 메모리 영역을 다시 사용하려는 시도가 불가능하다.

  • Double-Free: 동일한 메모리 영역을 두 번 해제하려는 시도가 불가능하다.

이러한 자동화된 메모리 관리는 코드의 안정성을 높일 뿐만 아니라, 개발자가 비즈니스 로직에 더 집중할 수 있게 하여 생산성을 향상시키는 부수적인 효과도 가져온다.21

2.3.2 포인터 부재와 참조 모델: 버퍼 오버플로우의 근본적 차단

C/C++에서 가장 악명 높은 취약점 중 하나는 ’버퍼 오버플로우(Buffer Overflow)’이다. 이는 프로그램이 할당된 메모리 버퍼의 경계를 넘어 데이터를 쓸 때 발생하며, 인접한 메모리 영역을 덮어쓰게 된다.23 공격자들은 이 취약점을 악용하여 함수의 반환 주소(return address)가 저장된 스택 영역을 덮어쓰고, 자신이 삽입한 악성 코드(셸코드)의 주소로 변경하여 시스템의 제어권을 탈취할 수 있다.19 이러한 공격이 가능한 근본적인 이유는 C/C++가 ’포인터(pointer)’를 통해 메모리 주소에 직접 접근하고, 포인터 연산(pointer arithmetic)을 통해 임의의 메모리 위치를 조작하는 것을 허용하기 때문이다.16

자바는 이러한 위협을 근본적으로 차단하기 위해 포인터와 직접적인 메모리 주소 조작 기능을 언어 사양에서 완전히 배제했다.2 대신 자바는 ’참조(reference)’라는 개념을 사용한다.16 자바의 참조는 C/C++의 포인터와 유사하게 객체를 가리키지만, 다음과 같은 결정적인 차이점이 있다.

  • 추상화된 식별자: 참조는 실제 메모리 주소가 아니라, JVM이 관리하는 객체에 대한 추상적인 식별자이다. 개발자는 참조를 통해 메모리 주소를 직접 볼 수도, 조작할 수도 없다.17

  • 포인터 연산 불가: 참조에 정수를 더하거나 빼는 등의 포인터 연산이 불가능하다. 이로 인해 할당된 메모리 영역을 벗어나 다른 영역을 침범하는 행위가 원천적으로 차단된다.16

  • 자동 경계 검사: 자바는 모든 배열 접근에 대해 런타임에 경계 검사(bounds checking)를 수행한다. 만약 인덱스가 배열의 크기를 벗어나면, ArrayIndexOutOfBoundsException 예외가 발생하여 프로그램 실행이 즉시 중단된다.2 이는 버퍼 오버플로우를 방지하는 매우 효과적인 안전장치다.

이러한 설계적 차이는 단순히 코딩 스타일의 문제가 아니라, 보안 패러다임의 근본적인 차이를 의미한다. C/C++의 보안 모델이 개발자의 세심한 주의와 올바른 라이브러리 사용에 크게 의존하는 반면, 자바는 언어와 런타임 자체에 메모리 손상 취약점을 방어하는 강력한 메커니즘을 내장하고 있다. 이는 자바의 보안이 우연한 결과가 아니라, 의도된 설계의 산물임을 명확히 보여준다.

2.3.3 강력한 정적 타이핑: 개발 단계에서의 오류 예방

자바는 강력한 정적 타입(strongly and statically typed) 언어이다.14 이는 모든 변수와 표현식의 타입이 컴파일 시점에 결정되고, 프로그램 실행 중에는 변경될 수 없음을 의미한다. 만약 타입이 호환되지 않는 연산을 시도하면, 코드는 컴파일조차 되지 않는다.29

이는 파이썬(Python)과 같은 동적 타입(dynamically typed) 언어와 대조된다. 동적 타입 언어에서는 변수의 타입이 런타임에 결정되므로, 개발 속도가 빠르고 유연하다는 장점이 있다.28 하지만 타입 관련 오류는 프로그램이 실행되고 해당 코드 블록이 실행될 때까지 발견되지 않을 수 있다.31

보안 관점에서 볼 때, 런타임에 발생하는 예기치 않은 TypeError는 단순한 버그를 넘어 잠재적인 보안 취약점이 될 수 있다. 이는 서비스 거부(Denial of Service) 공격으로 이어지거나, 애플리케이션을 예측 불가능하고 잠재적으로 불안정한 상태로 만들 수 있다. 자바의 정적 타입 시스템은 이러한 종류의 오류를 개발 단계에서 미리 차단하는 ‘예방적 보안(Proactive Security)’ 조치로 작용한다. 컴파일러가 타입 안전성을 강제함으로써, 런타임에 발생할 수 있는 잠재적 공격 표면(attack surface)을 사전에 줄이는 효과를 가져온다.31

표 1: 주요 프로그래밍 언어별 보안 특성 비교 (Java, C++, Python)

특성JavaC++Python
메모리 관리자동 (가비지 컬렉션)수동 (new/delete, malloc/free)자동 (가비지 컬렉션)
포인터없음 (참조 사용)지원 (직접 메모리 조작 가능)없음
타입 시스템정적, 강력 타입정적, 강력 타입동적, 강력 타입
배열 경계 검사자동 (런타임 예외 발생)수동 (기본적으로 검사 안 함)자동 (런타임 예외 발생)
주요 메모리 관련 취약점안전하지 않은 역직렬화버퍼 오버플로우, Use-After-Free타입 혼란(Type Confusion)을 이용한 공격 가능성

이 표는 자바가 C++에 비해 메모리 안전성 측면에서 구조적인 우위를 가지며, 파이썬에 비해 컴파일 시점의 사전 오류 검증을 통해 런타임 안정성을 확보하는 설계적 특징을 가지고 있음을 명확하게 보여준다. 이는 자바의 설계자들이 성능과 유연성 일부를 희생하는 대신, 안정성과 보안을 우선시하는 의도적인 선택을 했음을 시사한다.

3. 부: 오해의 근원: 과거의 유산과 현재의 도전 과제

자바 플랫폼이 설계적으로 견고한 방어 기제를 갖추고 있음에도 불구하고, ’자바는 보안에 취약하다’는 인식이 널리 퍼져 있는 것이 사실이다. 이 장에서는 이러한 오명이 형성된 역사적 원인을 분석하고, 그것이 현대 자바 플랫폼에 대한 유효한 평가인지 비판적으로 검토한다. 또한, 플랫폼 자체의 결함이 아닌 개발 관행과 생태계의 복잡성에서 비롯되는 현대 자바 애플리케이션의 실질적인 보안 도전 과제들을 심층적으로 다룬다.

3.1 역사 속으로 사라진 위협: 자바 애플릿의 보안 실패

자바에 대한 부정적인 보안 평판의 상당 부분은 ’자바 애플릿(Java Applet)’이라는 과거의 기술에 기인한다. 애플릿은 웹 브라우저 내에서 동적인 기능을 제공하기 위해 만들어진 작은 자바 프로그램으로, 웹 초창기에 큰 주목을 받았다.32 그러나 애플릿은 사용자의 명시적인 동의 없이 웹 페이지를 방문하는 것만으로도 자동으로 다운로드되고 실행되는 특성을 가지고 있었다.34 이 특성은 공격자들에게 매우 매력적인 표적이 되었고, 애플릿은 악성코드 유포의 주요 경로로 빈번하게 악용되었다.35

애플릿은 앞서 설명한 샌드박스 내에서 실행되도록 설계되었지만, 이 샌드박스 모델은 끊임없이 공격자들의 우회 시도에 직면했다. 실제로 JVM과 애플릿 실행 환경에서 수많은 보안 취약점이 발견되었고, 이를 통해 악성 코드가 샌드박스를 탈출하여 사용자 시스템을 감염시키는 사례가 빈번하게 발생했다.36 2012년에는 발견된 전체 웹 취약점 중 62%가 자바 애플릿 관련 취약점이라는 보고가 있을 정도로 심각한 문제였다.35

그러나 자바 애플릿의 보안 실패를 자바 언어 자체의 근본적인 결함으로 해석하는 것은 타당하지 않다. 문제의 핵심은 브라우저 플러그인이라는 실행 모델의 한계에 있었다. 애플릿은 NPAPI(Netscape Plugin API)와 같은 오래되고 표준화되지 않은 플러그인 기술에 의존했다.32 NPAPI는 보안에 매우 취약한 구조를 가지고 있었으며, 이는 자바 애플릿뿐만 아니라 Adobe Flash와 같은 다른 플러그인 기술에서도 공통적으로 나타나는 문제였다.39

결국 모든 주요 브라우저 벤더들은 보안상의 이유로 NPAPI에 대한 지원을 단계적으로 중단하고 완전히 제거했다.41 브라우저의 지원이 끊기면서 자바 애플릿은 기술적으로 실행될 수 있는 환경을 잃고 자연스럽게 시장에서 퇴출되었다. 이에 발맞춰 오라클 역시 Java 9에서 Applet API를 사용 중단(deprecated) 처리했으며, 마침내 Java 17에서는 향후 릴리스에서 완전히 제거될 것임을 공식화했다.32

결론적으로, 자바의 보안에 대한 부정적 인식은 대부분 더 이상 존재하지 않는, 역사 속으로 사라진 기술에 대한 기억에 기반하고 있다. 현대 자바 플랫폼의 보안성을 애플릿의 실패 사례로 평가하는 것은, 마치 최신 운영체제의 보안 수준을 20년 전의 바이러스 위협을 기준으로 판단하는 것과 같은 오류이다. 현대 자바 애플리케이션은 서버 환경에서 실행되며, 브라우저 플러그인 모델과는 전혀 다른 보안 컨텍스트를 가진다. 따라서 애플릿의 유산과 현대 자바의 보안 현실은 명확히 분리하여 평가해야 한다.

3.2 플랫폼이 아닌 코드의 문제: OWASP Top 10과 자바

현대 자바 애플리케이션, 특히 웹 애플리케이션은 OWASP(Open Web Application Security Project)에서 발표하는 Top 10 목록에 명시된 다양한 보안 위협에 노출되어 있다.45 이 목록에는 주입(Injection), 인증 및 접근 제어 실패(Identification and Authentication Failures, Broken Access Control), 취약하고 오래된 구성 요소 사용(Vulnerable and Outdated Components) 등이 포함된다.

그러나 이러한 취약점들이 자바 애플리케이션에서 발견된다는 사실이 자바 플랫폼 자체의 결함을 의미하는 것은 아니다. 대부분의 경우, 이들은 플랫폼이 제공하는 안전한 기능을 사용하지 않거나 부적절하게 사용하는 개발자의 코딩 관행에서 비롯된다.

3.2.1 SQL 인젝션(SQL Injection)

SQL 인젝션은 공격자가 웹 애플리케이션의 입력 필드를 통해 악의적인 SQL 구문을 삽입하여 데이터베이스를 비정상적으로 조작하는 공격이다.48 이 취약점은 사용자 입력을 검증하거나 필터링하지 않고, 문자열을 단순히 이어 붙이는 방식(string concatenation)으로 동적 SQL 쿼리를 생성할 때 발생한다.49

Java

// 취약한 코드 예시
String userName = request.getParameter("userName");
String query = "SELECT * FROM users WHERE name = '" + userName + "'";
Statement stmt = connection.createStatement();
ResultSet rs = stmt.executeQuery(query);

위 코드에서 만약 사용자가 userName으로 ' OR '1'='1 과 같은 값을 입력하면, 최종 쿼리는 SELECT * FROM users WHERE name = '' OR '1'='1' 이 되어 모든 사용자 정보를 반환하게 된다.

이러한 취약점은 자바 언어의 문제가 아니다. 자바는 JDBC API를 통해 이를 방어하기 위한 매우 강력하고 효과적인 메커니즘인 PreparedStatement(매개변수화된 쿼리, Parameterized Query)를 제공한다.50

Java

// 안전한 코드 예시
String userName = request.getParameter("userName");
String query = "SELECT * FROM users WHERE name =?";
PreparedStatement pstmt = connection.prepareStatement(query);
pstmt.setString(1, userName);
ResultSet rs = pstmt.executeQuery();

PreparedStatement를 사용하면, SQL 쿼리의 구조(코드)와 사용자 입력(데이터)이 명확하게 분리된다. 데이터베이스는 ? 위치에 바인딩된 사용자 입력을 절대로 실행 가능한 코드로 해석하지 않고, 순수한 데이터 값으로만 취급한다. 따라서 공격자가 악의적인 SQL 구문을 입력하더라도 쿼리의 의도가 변경되지 않아 공격이 원천적으로 차단된다.51 결국 SQL 인젝션 취약점은 자바가 제공하는 안전한 API를 사용하지 않은 개발자의 선택에서 비롯되는 문제이다.

3.2.2 크로스 사이트 스크립팅(Cross-Site Scripting, XSS)

XSS는 공격자가 악의적인 스크립트(주로 JavaScript)를 웹 페이지에 삽입하고, 다른 사용자의 브라우저에서 해당 스크립트가 실행되도록 만드는 공격이다.52 이 공격은 사용자로부터 입력받은 데이터를 적절한 검증이나 변환(인코딩, 살균) 과정 없이 그대로 HTML 페이지에 출력할 때 발생한다.54

예를 들어, 게시판 댓글에 <script>alert('XSS');</script> 와 같은 내용을 입력하고, 서버가 이 내용을 그대로 다른 사용자에게 보여주면, 해당 페이지를 보는 모든 사용자의 브라우저에서 경고창이 뜨게 된다. 이를 악용하면 사용자의 세션 쿠키를 탈취하거나, 악성 사이트로 리디렉션하는 등 심각한 피해를 유발할 수 있다.53

XSS 역시 자바 언어의 문제가 아닌, 모든 웹 애플리케이션 기술에서 공통으로 발생하는 입력 및 출력 처리의 문제이다. 이 문제를 해결하기 위한 핵심 원칙은 절대 사용자 입력을 신뢰하지 않고, 출력 시에는 항상 컨텍스트에 맞는 인코딩을 수행하는 것이다.56 Thymeleaf, JSP(JSTL 사용 시)와 같은 현대 자바 웹 템플릿 엔진들은 기본적으로 변수 값을 출력할 때 <, > 와 같은 HTML 특수 문자를 $lt;, $gt; 와 같은 엔티티(entity)로 자동 변환(escaping)하는 기능을 제공한다.54 이 기능은 개발자가 특별히 비활성화하지 않는 한, XSS 공격을 효과적으로 방어한다.

결론적으로, OWASP Top 10에 해당하는 대부분의 취약점은 자바 플랫폼이 제공하는 보안 도구와 프레임워크를 올바르게 활용함으로써 충분히 예방할 수 있다. 자바의 보안 모델은 “모든 것을 자동으로 해결해주는” 모델이 아니라, “안전한 애플리케이션을 구축할 수 있는 강력한 도구를 제공하는” 모델에 가깝다. 따라서 애플리케이션의 보안 수준은 플랫폼의 견고함만큼이나 개발자의 보안 인식과 실천에 달려있다.

3.3 자바의 아킬레스건: 안전하지 않은 역직렬화(Insecure Deserialization)의 위협

앞서 다룬 취약점들이 주로 개발자의 부주의한 코딩 관행에서 비롯된 것이라면, ’안전하지 않은 역직렬화’는 자바 플랫폼의 고유한 메커니즘과 생태계의 복잡성이 결합하여 발생하는, 훨씬 더 근본적이고 심각한 위협이다. 이는 OWASP Top 10에서도 ‘소프트웨어 및 데이터 무결성 실패(Software and Data Integrity Failures)’ 항목의 주요 원인으로 지목되며, 성공 시 원격 코드 실행(Remote Code Execution, RCE)이라는 치명적인 결과로 이어질 수 있다.45

직렬화(Serialization)는 자바 객체를 바이트 스트림(byte stream)으로 변환하여 파일에 저장하거나 네트워크를 통해 전송할 수 있게 하는 메커니즘이다. 역직렬화(Deserialization)는 이 바이트 스트림을 다시 원래의 자바 객체로 복원하는 과정이다.59 이 기능 자체는 매우 유용하지만, 그 구현 방식에 근본적인 위험이 내재되어 있다.

문제의 핵심은 ObjectInputStreamreadObject() 메서드가 동작하는 방식에 있다. 이 메서드가 신뢰할 수 없는 소스로부터 받은 바이트 스트림을 처리할 때, 다음과 같은 위험한 특성이 나타난다.

  • 생성자 없는 객체 생성: readObject()는 클래스의 생성자를 호출하지 않고도 객체를 메모리에 인스턴스화할 수 있다. 이는 객체 생성 시 수행되어야 할 초기화나 유효성 검사 로직을 우회할 수 있음을 의미한다.61

  • 임의의 클래스 인스턴스화: 공격자는 바이트 스트림을 조작하여, 애플리케이션의 클래스패스(classpath)에 존재하는 거의 모든 Serializable 인터페이스를 구현한 클래스의 객체를 생성하도록 강제할 수 있다.57

공격은 이러한 특성을 교묘하게 이용한다. 공격자는 악성 코드를 직접 바이트 스트림에 삽입하는 것이 아니다. 대신, 애플리케이션이 의존하는 라이브러리(예: Apache Commons Collections) 내에 합법적으로 존재하는 클래스들 중, 역직렬화 과정에서 자동으로 호출되는 ‘매직 메서드’(예: readObject, readResolve, finalize)를 가진 클래스들을 찾아낸다. 이러한 클래스들을 ’가젯(gadget)’이라고 부른다.61

공격자는 ysoserial과 같은 도구를 사용하여, 여러 가젯들을 마치 체인처럼 연결한 악의적인 객체 그래프를 포함하는 바이트 스트림(페이로드)을 생성한다.58 애플리케이션이 이 페이로드를 역직렬화하면, 첫 번째 가젯의 매직 메서드가 호출되고, 이 메서드가 다시 두 번째 가젯의 메서드를 호출하는 식으로 연쇄 반응이 일어난다. 이 ’가젯 체인(gadget chain)’의 마지막 단계에서는 Runtime.getRuntime().exec()와 같은 위험한 메서드가 호출되어, 공격자가 의도한 임의의 명령이 서버에서 실행되게 된다.58

이 공격 방식이 특히 위험한 이유는, 애플리케이션의 소스 코드에는 단 한 줄의 취약한 코드도 없을 수 있다는 점이다. 취약점은 특정 코드 라인의 버그가 아니라, 역직렬화 메커니즘과 클래스패스에 존재하는 수많은 라이브러리 클래스들 간의 예기치 않은 상호작용, 즉 **생태계의 복잡성에서 비롯되는 창발적 속성(emergent property)**이다. 개발자가 인지하지 못하는 사이에, 새로 추가한 라이브러리가 새로운 가젯을 제공하여 애플리케이션에 치명적인 RCE 취약점을 만들 수도 있다.

이러한 이유로 보안 전문가들은 **“신뢰할 수 없는 데이터는 절대 역직렬화하지 말라”**는 원칙을 강력하게 강조한다.61 자바의 역직렬화 메커니즘은 그 자체로 강력한 공격 벡터가 될 수 있으며, 이는 자바 플랫폼이 직면한 가장 심각하고 본질적인 보안 도전 과제 중 하나로 남아있다.

4. 부: 끊임없이 진화하는 보안 패러다임: 현대 자바의 대응

자바 플랫폼은 과거의 유산에 머무르지 않고, 변화하는 위협 환경과 새로운 기술 패러다임에 맞춰 보안 아키텍처를 끊임없이 현대화하고 있다. 특히 최근의 장기 지원(LTS) 릴리스들은 과거의 불필요한 보안 요소를 과감히 제거하는 동시에, 현대적인 위협에 대응하기 위한 정교하고 강력한 방어 메커니즘을 도입하는 전략적 진화를 보여준다. 이 장에서는 이러한 변화를 주도하는 핵심적인 기술적 결정과 기능 강화를 구체적으로 분석한다.

4.1 보안 관리자의 퇴장과 새로운 접근법 (JEP 411)

Java 17에서는 자바 보안의 상징과도 같았던 ’보안 관리자(Security Manager)’가 향후 릴리스에서 제거될 예정으로, 사용 중단(deprecated for removal) 처리되었다.44 언뜻 보기에 이는 자바의 보안 기능이 약화되는 것처럼 보일 수 있다. 그러나 JEP 411에서 밝힌 제거 이유는 오히려 자바 보안의 성숙과 패러다임 전환을 명확히 보여준다.

보안 관리자를 제거하기로 한 결정의 배경에는 다음과 같은 복합적인 요인이 있다.62

  • 시대적 부적합성과 낮은 사용률: 보안 관리자는 본래 신뢰할 수 없는 자바 애플릿 코드를 샌드박스 환경에서 안전하게 실행하기 위해 설계되었다. 그러나 애플릿 기술이 완전히 사장된 지금, 그 존재 이유가 희미해졌다. 서버 측 코드 보안을 위해 사용된 경우는 극히 드물었다.62

  • 과도한 유지보수 비용과 복잡성: 보안 관리자는 JDK의 수많은 클래스와 깊게 얽혀 있어, 새로운 API를 추가할 때마다 호환성을 고려해야 하는 등 막대한 유지보수 비용을 유발했다.62

  • 심각한 성능 저하: 보안 관리자가 활성화되면, 모든 리소스 접근 시점에 복잡한 권한 검사를 수행해야 하므로 애플리케이션의 성능이 크게 저하된다. 이 때문에 보안 관리자는 기본적으로 비활성화되어 있었다.62

  • 현대적 위협에 대한 비효율성: 보안 관리자는 코드의 출처를 기반으로 권한을 제어하는 모델이다. 하지만 SQL 인젝션, 역직렬화 공격 등 악의적인 ’데이터’를 통해 시스템을 공격하는 현대적인 위협에는 거의 무력하다.62

보안 관리자의 제거는 단순히 기능을 하나 없애는 것이 아니라, 낡고 비효율적인 프로세스 내부(in-process) 보안 모델을 버리고, 더 효과적이고 현대적인 보안 패러다임으로 전환하는 전략적 결정이다. 자바 플랫폼은 이제 다음과 같은 접근법을 통해 보안을 강화하고 있다.

  1. 강력한 캡슐화 (Strong Encapsulation): Java 9에서 도입된 모듈 시스템을 기반으로, JDK의 내부 구현 API에 대한 외부 접근을 기본적으로 차단한다 (JEP 403).65 이는 플랫폼의 무결성을 강화하고, 예측 불가능한 동작으로 인한 보안 허점을 줄인다.

  2. 프로세스 외부 격리 (Out-of-Process Isolation): 개별 코드 조각을 감시하는 대신, 애플리케이션 전체를 하나의 단위로 보고, 운영체제 수준의 기능이나 도커(Docker)와 같은 컨테이너 기술을 활용하여 외부 환경으로부터 격리한다. 이는 훨씬 더 강력하고 성능 저하가 적은 현대적인 격리 방식이다.62

결론적으로, 보안 관리자의 퇴장은 자바 보안의 후퇴가 아니라, 현실적인 위협에 보다 효과적으로 대응하기 위한 합리적인 진화 과정이다. 이는 자바 플랫폼이 레거시 기술을 과감히 정리하고, 더 효율적이고 강력한 현대적 보안 체계로 나아가고 있음을 보여주는 명백한 증거다.

4.2 최신 LTS 릴리스의 보안 강화: JDK 11, 17, 21

오라클은 장기 지원(LTS) 릴리스를 통해 자바 플랫폼의 안정성뿐만 아니라 보안 기능도 지속적으로 강화하고 있다. 각 LTS 버전은 최신 암호화 표준을 지원하고, 알려진 취약점을 해결하며, 미래의 위협에 대비하기 위한 새로운 보안 기능을 도입하는 명확한 로드맵을 보여준다.67

  • JDK 11:

  • TLS 1.3 지원 (JEP 332): 전송 계층 보안(Transport Layer Security)의 최신 버전인 TLS 1.3을 표준으로 지원한다.68 TLS 1.3은 이전 버전에 비해 핸드셰이크 과정을 단순화하여 성능을 개선하고, 구식이고 취약한 암호화 알고리즘을 제거하여 보안을 대폭 강화했다. 이를 통해 자바 애플리케이션은 별도의 설정 없이도 기본적으로 더 빠르고 안전한 네트워크 통신을 수행할 수 있게 되었다.

  • JDK 17:

  • 레거시 기술 제거 및 플랫폼 무결성 강화: 앞서 언급했듯이, 보안 관리자(JEP 411)와 Applet API(JEP 398)를 제거 대상으로 지정하여 과거의 보안 위협 요소를 본격적으로 정리하기 시작했다.44 동시에, **JDK 내부 API의 강력한 캡슐화를 기본값으로 설정(JEP 403)**하여, 개발자가 sun.misc.Unsafe와 같은 비표준 내부 구현에 의존하는 것을 어렵게 만들었다.65 이는 플랫폼의 안정성과 예측 가능성을 높여 잠재적인 보안 문제를 예방하는 중요한 조치다.

  • 향상된 의사 난수 생성기 (JEP 356): 다양한 의사 난수 생성기(PRNG) 알고리즘을 위한 새로운 인터페이스와 구현을 제공하여, 특정 구현에 종속되지 않고 요구사항에 맞는 알고리즘을 쉽게 선택하고 사용할 수 있도록 개선했다.44

  • JDK 21:

  • 양자내성암호(Post-Quantum Cryptography, PQC) 준비: 미래의 양자 컴퓨터가 기존 공개키 암호 체계를 무력화시킬 위협에 대비하기 위한 선제적인 조치를 시작했다. **키 캡슐화 메커니즘(Key Encapsulation Mechanism, KEM)을 위한 표준 API(JEP 452)**를 도입하여, 양자 컴퓨터의 공격에도 안전한 것으로 알려진 새로운 암호화 알고리즘을 자바 플랫폼에 통합할 수 있는 기반을 마련했다.70

  • 최신 암호화 알고리즘 지원: XML 디지털 서명에서 기존의 RSA나 DSA보다 더 안전하고 효율적인 최신 EdDSA(Edwards-Curve Digital Signature Algorithm) 알고리즘을 지원하기 시작했다.70 이는 자바가 최신 암호화 표준을 적극적으로 수용하고 있음을 보여준다.

이러한 지속적인 개선은 자바의 보안이 정체되어 있지 않고, 현재와 미래의 위협에 대응하기 위해 끊임없이 진화하고 있음을 명확하게 증명한다.

표 2: 최신 JDK LTS 릴리스별 핵심 보안 강화 사항

JDK 버전주요 보안 강화 JEP/기능보안상 의미
JDK 11TLS 1.3 지원 (JEP 332)더 빠르고 안전한 최신 표준 암호화 통신을 기본으로 제공하여 네트워크 보안 강화.
JDK 17보안 관리자 Deprecate (JEP 411)
JDK 내부 캡슐화 (JEP 403)
레거시 보안 모델을 제거하고 현대화.
플랫폼의 무결성을 강화하고 비표준 API 의존성 제거.
JDK 21KEM API (JEP 452)
EdDSA XML 서명 지원
미래의 양자 컴퓨터 위협에 대비한 양자내성암호(PQC) 기반 마련.
더 강력하고 효율적인 최신 암호화 표준을 도입하여 디지털 서명 보안 강화.

4.3 역직렬화 공격에 대한 능동적 방어: 컨텍스트 기반 필터링 (JEP 415)

자바 플랫폼은 가장 심각한 위협 중 하나인 ‘안전하지 않은 역직렬화’ 공격에 대응하기 위해 수동적인 자세에서 벗어나 능동적인 방어 체계를 구축해왔다. 그 시작은 Java 9에서 도입된 JEP 290으로, 개발자가 허용하거나 거부할 클래스 목록을 지정하여 역직렬화 과정을 필터링할 수 있는 기본적인 메커니즘을 제공했다.71

그러나 이 방식은 애플리케이션 전반에 걸쳐 단일 필터를 적용해야 하는 한계가 있었다. 복잡한 애플리케이션에서는 각기 다른 모듈이나 컴포넌트가 서로 다른 종류의 객체를 역직렬화해야 할 수 있는데, 단일 필터로는 이러한 다양한 요구사항을 유연하게 처리하기 어려웠다.

이러한 한계를 극복하기 위해 Java 17에서는 **JEP 415: 컨텍스트 기반 역직렬화 필터(Context-Specific Deserialization Filters)**가 도입되었다.65 이 기능의 핵심은 **JVM-wide 필터 팩토리(filter factory)**의 도입이다.71 필터 팩토리는 개별 ObjectInputStream이 생성될 때마다 호출되어, 해당 스트림에 적용할 맞춤형 필터를 동적으로 제공하는 역할을 한다.72

이러한 접근 방식은 역직렬화 방어에 있어 패러다임의 전환을 의미한다. 기존의 정적이고 전역적인 필터링에서 벗어나, 각 역직렬화 작업이 발생하는 ’맥락(context)’을 기반으로 한 동적이고 정교한 정책 시행이 가능해졌다.

  • 동적 필터 선택: 필터 팩토리는 역직렬화를 요청한 클래스, 모듈, 또는 현재 스레드의 상태 등 다양한 런타임 정보를 바탕으로 어떤 필터를 적용할지 결정할 수 있다. 예를 들어, 이미지 처리 모듈에서는 java.awt.Image 관련 클래스만 허용하고, 사용자 프로필 관리 모듈에서는 com.example.UserProfile 클래스만 허용하는 식으로 매우 세분화된 규칙을 적용할 수 있다.71

  • 최소 권한 원칙 적용: 이는 역직렬화 과정에 ’최소 권한의 원칙(Principle of Least Privilege)’을 적용한 것이다. 각 컴포넌트는 자신의 기능 수행에 반드시 필요한 클래스만 역직렬화할 수 있도록 제한함으로써, 공격자가 하나의 취약점을 통해 애플리케이션 전체를 장악할 가능성을 크게 줄인다.

  • 유연성과 중앙 관리: 필터 팩토리를 통해 필터링 로직을 중앙에서 관리하면서도, 각기 다른 컨텍스트에 맞게 유연하게 정책을 적용할 수 있다. 이는 복잡한 대규모 애플리케이션의 보안을 효과적으로 관리하는 데 매우 중요하다.

JEP 415는 자바가 역직렬화라는 근본적인 위협에 대해 단순히 문제를 인지하는 것을 넘어, 매우 정교하고 강력한 방어 체계를 플랫폼 수준에서 제공하기 시작했음을 보여준다. 이는 정적인 블랙리스트 방식에서 벗어나, 애플리케이션의 내부 구조와 신뢰 경계를 이해하는 동적이고 지능적인 보안 정책 엔진으로 진화하고 있음을 의미한다.

5. 결론: 종합 평가 및 보안 강화를 위한 제언

5.1 종합 평가

“자바 언어 자체가 보안 이슈가 많은가?“라는 초기 질문에 대한 본 보고서의 최종적인 답변은 ’그렇지 않다’에 가깝다. 자바 언어와 JVM 플랫폼은 설계 초기부터 보안을 핵심 가치로 삼아 구축되었다. 자동 메모리 관리(가비지 컬렉션), 포인터의 부재, 강력한 타입 시스템, 바이트코드 검증, 샌드박스 모델 등은 C/C++과 같은 언어에서 발생하는 버퍼 오버플로우와 같은 치명적인 저수준(low-level) 메모리 손상 취약점을 원천적으로 방어하는 견고한 기반을 제공한다.

자바의 보안에 대한 오랜 부정적 평판은 대부분 현재는 완전히 사장된 ‘자바 애플릿’ 기술의 실패에 기인한다. 브라우저 플러그인 모델의 고유한 취약점에서 비롯된 이 문제는 현대 서버사이드 자바 플랫폼의 보안성을 평가하는 데 더 이상 유효한 기준이 될 수 없다. 오히려 오라클과 오픈소스 커뮤니티는 최신 LTS 릴리스를 통해 TLS 1.3 지원, 레거시 보안 기능(보안 관리자)의 과감한 제거, 양자내성암호 준비 등 끊임없이 변화하는 위협 환경에 맞춰 플랫폼을 적극적으로 현대화하고 있다.

5.2 책임의 공유

그러나 플랫폼의 내재적 견고함이 그 위에서 실행되는 모든 애플리케이션의 절대적인 안전을 보장하지는 않는다. SQL 인젝션, 크로스 사이트 스크립팅(XSS), 그리고 특히 자바 고유의 심각한 위협인 ’안전하지 않은 역직렬화’와 같은 현대적인 보안 취약점들은 대부분 플랫폼의 결함이 아닌, 개발자의 코딩 관행, 외부 라이브러리에 대한 의존성 관리의 미비, 그리고 보안 기능에 대한 이해 부족에서 비롯된다.

이는 자바의 보안이 플랫폼 혼자만의 책임이 아니라, 플랫폼 제공자, 애플리케이션 개발자, 그리고 라이브러리 생태계가 함께 책임을 지는 **공유 책임 모델(Shared Responsibility Model)**의 성격을 띠고 있음을 명확히 보여준다. 플랫폼은 안전한 집을 지을 수 있는 견고한 자재(안전한 API, 강력한 런타임)를 제공하지만, 그 자재를 사용하여 안전한 구조물을 설계하고 건축하는 것은 결국 개발자의 몫이다.

5.3 핵심 제언

따라서 안전하고 견고한 자바 애플리케이션을 구축하기 위해서는 플랫폼이 제공하는 기능을 최대한 활용하는 동시에, 개발 프로세스 전반에 걸쳐 보안을 내재화하는 노력이 반드시 필요하다. 이를 위해 다음 네 가지 핵심 사항을 제언한다.

  1. 최신 LTS 버전의 적극적인 도입: 보안은 정적인 상태가 아니라 지속적인 과정이다. 오라클은 3년(최근 2년으로 단축) 주기의 LTS 릴리스를 통해 새로운 보안 기능을 도입하고 알려진 취약점을 패치하고 있다. 가능한 한 지원이 활발한 최신 LTS 버전을 사용하는 것은 새로운 위협에 대응하는 가장 기본적이고 효과적인 조치다.

  2. 안전한 코딩 관행의 생활화: OWASP Top 10과 같은 표준 보안 가이드라인을 숙지하고 모든 개발자가 이를 준수하도록 해야 한다. 특히 사용자 입력을 다루는 모든 코드 경로에서 PreparedStatement 사용, 입출력 값에 대한 철저한 유효성 검증 및 컨텍스트에 맞는 인코딩, 그리고 비즈니스 로직에 부합하는 접근 제어 구현 등 방어적인 코딩(Defensive Coding)을 개발 문화의 일부로 정착시켜야 한다.

  3. 의존성 관리 및 지속적인 스캐닝: 현대 애플리케이션은 수많은 외부 라이브러리(의존성) 위에 구축된다. 이 라이브러리들은 잠재적인 공격 벡터가 될 수 있으며, 특히 역직렬화 공격의 ’가젯’을 제공하는 통로가 될 수 있다. 의존성 스캐닝 도구(SCA, Software Composition Analysis)를 CI/CD 파이프라인에 통합하여, 프로젝트가 사용하는 모든 직접 및 전이 의존성(transitive dependencies)에 대해 알려진 취약점을 지속적으로 탐지하고, 발견 시 즉시 최신 버전으로 업데이트하는 프로세스를 수립해야 한다.

  4. 역직렬화의 신중한 사용 및 필터링 강화: 가능하면 자바 네이티브 직렬화 대신, 스키마 기반의 더 안전한 데이터 교환 포맷(예: JSON, Protocol Buffers, Avro)을 사용하는 것을 최우선으로 고려해야 한다. 부득이하게 네이티브 역직렬화를 사용해야 한다면, Java 17 이상에서 제공하는 JEP 415의 컨텍스트 기반 필터링 기능을 적극적으로 활용해야 한다. 특정 컨텍스트에서 반드시 필요한 클래스만 명시적으로 허용하는 ‘허용 목록(allow-list)’ 접근법을 채택하여 공격 표면을 최소화해야 한다.

6. Works cited

  1. 샌드박스 (컴퓨터 보안) - 오늘의AI위키, AI가 만드는 백과사전, accessed October 28, 2025, https://wiki.onul.works/w/%EC%83%8C%EB%93%9C%EB%B0%95%EC%8A%A4_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EB%B3%B4%EC%95%88)
  2. Security of the Java software platform - Wikipedia, accessed October 28, 2025, https://en.wikipedia.org/wiki/Security_of_the_Java_software_platform
  3. 샌드박스 (컴퓨터 보안) - 위키백과, 우리 모두의 백과사전, accessed October 28, 2025, https://ko.wikipedia.org/wiki/%EC%83%8C%EB%93%9C%EB%B0%95%EC%8A%A4_(%EC%BB%B4%ED%93%A8%ED%84%B0_%EB%B3%B4%EC%95%88)
  4. SandBox란? :: 불곰, accessed October 28, 2025, https://brownbears.tistory.com/78
  5. Java SE Platform Security Architecture - Oracle Help Center, accessed October 28, 2025, https://docs.oracle.com/en/java/javase/11/security/java-se-platform-security-architecture.html
  6. m.hanbit.co.kr, accessed October 28, 2025, https://m.hanbit.co.kr/channel/view.html?cmscode=CMS3775387032#:~:text=Security%20manager%EB%8A%94%20java.lang,%EA%B2%80%EC%82%AC%ED%95%98%EB%8A%94%20%EC%97%AD%ED%95%A0%EC%9D%84%20%ED%95%9C%EB%8B%A4.
  7. Java 보안 관리자 사용 - IBM, accessed October 28, 2025, https://www.ibm.com/docs/ko/cics-ts/5.6?topic=applications-enabling-java-security-manager
  8. [Java] 자바 동작 과정 - 혼자하는 코딩 - 티스토리, accessed October 28, 2025, https://gofo-coding.tistory.com/entry/Java-%EC%9E%90%EB%B0%94-%EB%8F%99%EC%9E%91-%EA%B3%BC%EC%A0%95
  9. JVM과 자바 실행 과정 알아보기 - 개발 여정 - 티스토리, accessed October 28, 2025, https://devstep.tistory.com/76
  10. 자바 컴파일 과정: 소스코드부터 실행까지 - velog, accessed October 28, 2025, https://velog.io/@taebong98/%EC%9E%90%EB%B0%94-%EC%BB%B4%ED%8C%8C%EC%9D%BC-%EA%B3%BC%EC%A0%95-%EC%86%8C%EC%8A%A4%EC%BD%94%EB%93%9C%EB%B6%80%ED%84%B0-%EC%8B%A4%ED%96%89%EA%B9%8C%EC%A7%80
  11. Java 프로그램 실행 과정. Java 컴파일러(JAVAC)가 Java로 프로그래밍된 소스코드를… | by SoqSoq | Medium, accessed October 28, 2025, https://medium.com/@soqlehsoqleh/java-%ED%94%84%EB%A1%9C%EA%B7%B8%EB%9E%A8-%EC%8B%A4%ED%96%89-%EA%B3%BC%EC%A0%95-80443506a480
  12. Java Security Overview - Oracle Help Center, accessed October 28, 2025, https://docs.oracle.com/en/java/javase/11/security/java-security-overview1.html
  13. Java Security Overview - Oracle Help Center, accessed October 28, 2025, https://docs.oracle.com/en/java/javase/24/security/java-security-overview1.html
  14. Java Security in 2023- Snyk | Snyk, accessed October 28, 2025, https://snyk.io/articles/java-security/
  15. Java Security Overview - Oracle Help Center, accessed October 28, 2025, https://docs.oracle.com/en/java/javase/17/security/java-security-overview1.html
  16. C/C++ Pointers vs Java references\n - Tutorials Point, accessed October 28, 2025, https://www.tutorialspoint.com/c-cplusplus-pointers-vs-java-references
  17. C/C++ Pointers vs Java References - GeeksforGeeks, accessed October 28, 2025, https://www.geeksforgeeks.org/java/c-cpp-pointers-vs-java-references/
  18. C++ vs Java : r/cs2a - Reddit, accessed October 28, 2025, https://www.reddit.com/r/cs2a/comments/1ghq18c/c_vs_java/
  19. Buffer Overflow - OWASP Foundation, accessed October 28, 2025, https://owasp.org/www-community/vulnerabilities/Buffer_Overflow
  20. 자바 메모리 관리 - 가비지 컬렉션 - YABOONG, accessed October 28, 2025, https://yaboong.github.io/java/2018/06/09/java-garbage-collection/
  21. Java 가비지 컬렉션이란 무엇인가요? - IBM, accessed October 28, 2025, https://www.ibm.com/kr-ko/think/topics/garbage-collection-java
  22. JAVA 가비지 콜렉션의 활동 원리 - AI_Nomads - Inblog, accessed October 28, 2025, https://inblog.ai/nomads/java-%EA%B0%80%EB%B9%84%EC%A7%80-%EC%BD%9C%EB%A0%89%EC%85%98%EC%9D%98-%ED%99%9C%EB%8F%99-%EC%9B%90%EB%A6%AC-7857?traffic_type=internal
  23. Buffer overflow attacks in C++: A hands-on guide | Snyk, accessed October 28, 2025, https://snyk.io/blog/buffer-overflow-attacks-in-c/
  24. Buffer overflow - Wikipedia, accessed October 28, 2025, https://en.wikipedia.org/wiki/Buffer_overflow
  25. Why are programs written in C and C++ so frequently vulnerable to overflow attacks?, accessed October 28, 2025, https://security.stackexchange.com/questions/115507/why-are-programs-written-in-c-and-c-so-frequently-vulnerable-to-overflow-attac
  26. Java vs C++ Comparison: Key Differences Between C++ and Java - Onix-Systems, accessed October 28, 2025, https://onix-systems.com/blog/learn-some-crucial-difference-between-c-and-java
  27. The Basics of Java Security - Baeldung, accessed October 28, 2025, https://www.baeldung.com/java-security-overview
  28. Static vs Dynamic, Strong vs Weak Typing — The Most Popular Languages Use One of Each | by Andreas Kagoshima | Medium, accessed October 28, 2025, https://medium.com/@a.kago1988/statically-vs-dynamically-strongly-vs-weakly-typed-languages-f50055d583cc
  29. What is the difference between statically typed and dynamically typed languages?, accessed October 28, 2025, https://stackoverflow.com/questions/1517582/what-is-the-difference-between-statically-typed-and-dynamically-typed-languages
  30. Finding the Best Fit Between Dynamic Typing vs. Static Typing - Unosquare, accessed October 28, 2025, https://www.unosquare.com/blog/finding-the-best-fit-between-dynamic-typing-vs-static-typing/
  31. Static vs Dynamic Typing: A Detailed Comparison - BairesDev, accessed October 28, 2025, https://www.bairesdev.com/blog/static-vs-dynamic-typing/
  32. Java Applet - 나무위키, accessed October 28, 2025, https://namu.wiki/w/Java%20Applet
  33. 자바 - 오늘의AI위키, AI가 만드는 백과사전, accessed October 28, 2025, https://wiki.onul.works/w/%EC%9E%90%EB%B0%94
  34. 자바 애플릿 활성화하는 게 사용자들한테 엄청난 보안 위험이라고 들었는데… 전통적인 자바 앱도 그런가? : r/java - Reddit, accessed October 28, 2025, https://www.reddit.com/r/java/comments/6owu8u/ive_heard_enabling_java_applets_is_a_huge/?tl=ko
  35. [빛스캔과 함께 하는 금주 보안동향] 자바 애플릿 취약점 이용 악성코드 급증 - 전자신문, accessed October 28, 2025, https://m.etnews.com/201207310312?obj=Tzo4OiJzdGRDbGFzcyI6Mjp7czo3OiJyZWZlcmVyIjtOO3M6NzoiZm9yd2FyZCI7czoxMzoid2ViIHRvIG1vYmlsZSI7fQ%3D%3D
  36. [Java] 왜/어떻게 Java 애플릿이 안전하지 않나요? 왜 만들면 안 되나요? 제 웹페이지에 작은 게임을 구현하는 편리한 방법 같은데요. : r/learnprogramming - Reddit, accessed October 28, 2025, https://www.reddit.com/r/learnprogramming/comments/1sh6he/java_whyhow_are_java_applets_insecure_why/?tl=ko
  37. Java Applet (r29 판) - 나무위키, accessed October 28, 2025, https://namu.wiki/w/Java%20Applet?uuid=c941af99-ecd3-41dd-a313-f14b055fd840
  38. 자바 애플릿·플래시 취약점 지닌 당신의 PC 노린다! - 보안뉴스, accessed October 28, 2025, https://www.boannews.com/media/view.asp?idx=32386&direct=mobile
  39. OMNIBUSCODE [WebBrowser] - 크롬의 NPAPI 지원 중지에 따른 대안, accessed October 28, 2025, https://www.omnibuscode.com/board/board_webbrowser/32648
  40. 한국, 크롬 NPAPI 지원 중단과 MS 엣지에 ‘벌벌’ - 이코노믹리뷰, accessed October 28, 2025, https://www.econovill.com/news/articleView.html?idxno=252014
  41. 자바가 왜 앱플릿을 비활성화했지? : r/java - Reddit, accessed October 28, 2025, https://www.reddit.com/r/java/comments/rw6fbb/why_did_java_disable_applet/?tl=ko
  42. 최신 버전 크롬에서 NPAPI를 어떻게 작동시킬 수 있을까? : r/chrome - Reddit, accessed October 28, 2025, https://www.reddit.com/r/chrome/comments/6eeu5g/how_to_get_npapi_to_work_in_newest_version_of/?tl=ko
  43. 구글 크롬 웹브라우저 NPAPI 플러그인 실행 활성화 설정 가이드 - 교육부전자서명인증센터, accessed October 28, 2025, https://www.epki.go.kr/boardCnts/fileDown.do?fileSeq=8e6516be140c36e53d606d05c9628c25
  44. Oracle Releases Java 17, accessed October 28, 2025, https://www.oracle.com/news/announcement/oracle-releases-java-17-2021-09-14/
  45. Index Top 10 - OWASP Cheat Sheet Series, accessed October 28, 2025, https://cheatsheetseries.owasp.org/IndexTopTen.html
  46. What is OWASP? What is the OWASP Top 10? - Cloudflare, accessed October 28, 2025, https://www.cloudflare.com/learning/security/threats/owasp-top-10/
  47. OWASP Top 10:2021, accessed October 28, 2025, https://owasp.org/Top10/
  48. What is a SQL Injection in Java? - Contrast Security, accessed October 28, 2025, https://www.contrastsecurity.com/developer/learn/sql-injection/java
  49. Data Security: Stop SQL Injection Attacks Before They Stop You | Microsoft Learn, accessed October 28, 2025, https://learn.microsoft.com/en-us/archive/msdn-magazine/2004/september/data-security-stop-sql-injection-attacks-before-they-stop-you
  50. How To Prevent SQL Injections in Java - Acunetix, accessed October 28, 2025, https://www.acunetix.com/how-to-prevent-sql-injections-java/
  51. SQL Injection Prevention - OWASP Cheat Sheet Series, accessed October 28, 2025, https://cheatsheetseries.owasp.org/cheatsheets/SQL_Injection_Prevention_Cheat_Sheet.html
  52. Cross-site scripting (XSS) - Security - MDN Web Docs, accessed October 28, 2025, https://developer.mozilla.org/en-US/docs/Web/Security/Attacks/XSS
  53. Cross Site Scripting (XSS) - OWASP Foundation, accessed October 28, 2025, https://owasp.org/www-community/attacks/xss/
  54. Mitigating & Preventing Cross-Site Scripting (XSS) Vulnerabilities …, accessed October 28, 2025, https://www.securityjourney.com/post/mitigating-preventing-cross-site-scripting-xss-vulnerabilities-an-example
  55. What is Cross-site Scripting (XSS): prevention and fixes - Acunetix, accessed October 28, 2025, https://www.acunetix.com/websitesecurity/cross-site-scripting/
  56. Preventing Java XSS Attacks: Examples & Solutions - StackHawk, accessed October 28, 2025, https://www.stackhawk.com/blog/java-xss/
  57. Insecure Deserialization - Und3r__Score__ - 티스토리, accessed October 28, 2025, https://und3rscore.tistory.com/2
  58. 자바 역직렬화 취약점 - 꼰머의 보안공부 - 티스토리, accessed October 28, 2025, https://ggonmerr.tistory.com/133
  59. 웹해킹 #14 자바 역직렬화 취약점 공격 - Ryuuuuuusy - 티스토리, accessed October 28, 2025, https://rsy99.tistory.com/61
  60. 자바 역 직렬화(Java Deserialization) 문제, accessed October 28, 2025, https://maxtive.tistory.com/12
  61. 자바 직렬화(Serializable) - 완벽 마스터하기 - Inpa Dev ‍ - 티스토리, accessed October 28, 2025, https://inpa.tistory.com/entry/JAVA-%E2%98%95-%EC%A7%81%EB%A0%AC%ED%99%94Serializable-%EC%99%84%EB%B2%BD-%EB%A7%88%EC%8A%A4%ED%84%B0%ED%95%98%EA%B8%B0
  62. JEP 411: Deprecate the Security Manager for Removal - OpenJDK, accessed October 28, 2025, https://openjdk.org/jeps/411
  63. Quality Outreach Heads-up - JDK 24: Retiring the Security Manager - Inside.java, accessed October 28, 2025, https://inside.java/2024/12/11/quality-heads-up/
  64. JEP 486: Permanently Disable the Security Manager - OpenJDK, accessed October 28, 2025, https://openjdk.org/jeps/486
  65. Significant Changes in JDK 17 Release - Oracle Help Center, accessed October 28, 2025, https://docs.oracle.com/en/java/javase/17/migrate/significant-changes-jdk-release.html
  66. Significant Changes in JDK 17 Release - Oracle Help Center, accessed October 28, 2025, https://docs.oracle.com/en/java/javase/24/migrate/significant-changes-jdk-17.html
  67. Java Security Resource Center - Oracle, accessed October 28, 2025, https://www.oracle.com/java/technologies/security.html
  68. JDK 11 Release Notes, Important Changes, and Information - Oracle, accessed October 28, 2025, https://www.oracle.com/java/technologies/javase/11-relnote-issues.html
  69. JDK 17 Release Notes, Important Changes, and Information - Oracle, accessed October 28, 2025, https://www.oracle.com/java/technologies/javase/17-relnote-issues.html
  70. JDK 21 Security Enhancements - Sean Mullan, accessed October 28, 2025, https://seanjmullan.org/blog/2023/09/22/jdk21
  71. Context-Specific Deserialization Filters in Java | Baeldung, accessed October 28, 2025, https://www.baeldung.com/java-context-specific-deserialization-filters
  72. JEP 415: Context-Specific Deserialization Filters - OpenJDK, accessed October 28, 2025, https://openjdk.org/jeps/415